class Solution {   //滑动窗口 + 哈希表 -》转化为[字符串中所有字母异位词]
public:
    vector<int> findSubstring(string s, vector<string>& words) {
    vector<int> ret; 
    unordered_map<string, int> hash2;  //words中单词出现的频次
    for(auto& e : words)  //将words中的所有的字符串放入哈希表
    {
        hash2[e]++;
    }

    int n2 = words.size(), len = words[0].size();
    for(int i = 0; i < len; i++) //执行滑动窗口的次数
    {
        unordered_map<string, int> hash1; //s中单词出现的频次
        //若right后字符长度<len,无需向后继续进行
        for(int left = i, right = i, count = 0; right + len <= s.size(); right += len)
        {
            string in = s.substr(right, len); //取出与words长度相等的子串
            ++hash1[in];
            //小细节：unordered_map容器，若[]内数据不存在，则需要重新插入，有一定的时间消耗，改进，该数据存在，才维护
            if(hash2.count(in) && hash1[in] <= hash2[in])  count++;  //进窗口 + 维护count

            if(right - left + 1 > n2*len) //判断
            {
                string out = s.substr(left, len); 
                if(hash2.count(out) && hash1[out] <= hash2[out]) count--; //维护count + 出窗口
                hash1[out]--; //&&,只要左边为假，就不执行右边
                left += len; //left移动的步长
            }
            
            if(count == n2)  ret.push_back(left);  //更新结果
        }
    }
    return ret;
    }
};